package com.fau.wmbj.server.storage;


import cn.hutool.core.builder.CompareToBuilder;
import cn.hutool.core.builder.EqualsBuilder;
import cn.hutool.core.builder.HashCodeBuilder;
import com.fau.wmbj.server.utils.Filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;

/**
 * 存储
 *
 * @author jiawei
 */
public abstract class Storage implements Comparable<Storage> {

    @Autowired
    private StorageConfigService storageConfigService;

    /**
     * 获取ID
     *
     * @return ID
     */
    public String getId() {
        return getClass().getAnnotation(Component.class).value();
    }

    /**
     * 获取名称
     *
     * @return 名称
     */
    public abstract String getName();


    /**
     * 获取插件配置
     *
     * @return 插件配置
     */
    public StorageConfig getStorageConfig() {
        String id = getId();
        StorageConfig storageConfig = storageConfigService.findEntity(Filter.eq("pluginId", id));
        return storageConfig;
    }

    /**
     * 获取是否已启用
     *
     * @return 是否已启用
     */
    public boolean getIsEnabled() {
        StorageConfig storageConfig = getStorageConfig();
        return storageConfig != null ? storageConfig.getIsEnabled() : false;
    }

    /**
     * 获取属性值
     *
     * @param name 属性名称
     * @return 属性值
     */
    public String getAttribute(String name) {
        StorageConfig storageConfig = getStorageConfig();
        return storageConfig != null ? storageConfig.getAttribute(name) : null;
    }

    /**
     * 获取排序
     *
     * @return 排序
     */
    public Integer getOrder() {
        StorageConfig storageConfig = getStorageConfig();
        return storageConfig != null ? storageConfig.getOrder() : null;
    }

    /**
     * 文件上传
     *
     * @param path      上传路径
     * @param file      上传文件
     * @param open      是否存储在开放空间
     * @param extension 文件后缀
     */
    public abstract String upload(String path, File file, String extension, boolean open) throws Exception;

    /**
     * 文件上传
     *
     * @param path          上传路径
     * @param multipartFile 上传文件
     * @param open          是否存储在开放空间
     * @return String 文件路径
     */
    public abstract String upload(String path, MultipartFile multipartFile, boolean open) throws Exception;

    /**
     * 文件删除
     *
     * @param storageDirectory 文件信息
     */
    public abstract void delete(StorageDirectory storageDirectory, boolean isPreview);

    /**
     * 文件删除
     *
     * @param url     文件路径
     * @param groupId 存储桶
     */
    public abstract void delete(String url, String groupId);

    /**
     * 获取访问URL
     *
     * @param storageDirectory 已上传文件
     * @param timeOut          0为长期有效
     * @return 访问URL设置链接有效期
     */
    public abstract String getUrl(StorageDirectory storageDirectory, boolean isPreview, int timeOut);

    /**
     * 获取服务端存储路径
     *
     * @param diskPath 上传路径
     * @return 访问URL
     */
    public abstract String getStoragePath(String diskPath);

    /**
     * 下载文件
     *
     * @param storageDirectory 文件详情
     * @param isPreview        是否下载预览文件
     */
    public abstract InputStream download(StorageDirectory storageDirectory, boolean isPreview);

    /**
     * 实现compareTo方法
     *
     * @param storage 存储插件
     * @return 比较结果
     */
    @Override
    public int compareTo(Storage storage) {
        if (storage == null) {
            return 1;
        }
        return new CompareToBuilder().append(getOrder(), storage.getOrder()).append(getId(), storage.getId()).toComparison();
    }

    /**
     * 重写equals方法
     *
     * @param obj 对象
     * @return 是否相等
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        Storage other = (Storage) obj;
        return new EqualsBuilder().append(getId(), other.getId()).isEquals();
    }

    /**
     * 重写hashCode方法
     *
     * @return HashCode
     */
    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37).append(getId()).toHashCode();
    }
}